#ifndef _UI_GRAPH_H_
#define _UI_GRAPH_H_

#include "ui_widget.h"
#include "ui_trsprite.h"

namespace ui
{
class UIGraph : public UIWidget
{
public:
/// stuff that every self-respecting widget should have
						UIGraph(UIWidget* pParent,const std::string& Name = "");
	virtual				~UIGraph();
	virtual bool		Create(const std::string& Name, const math::Vec2& Pos = math::Vec2(0.5f, 0.5f), const math::Vec2& Size= math::Vec2(0.1f, 0.1f));
	virtual	bool		Load(LuaPlus::LuaObject& _LObj);
	/// update
	virtual	bool		Tick(float dt);
	/// display
	virtual bool		Render(bool Force = false);
	/// register with LUA Bind
	static	void		Register(LuaPlus::LuaState* _pScript);

	//GRAPH-SPECIFIC STUFF

	//METHODS

	void				SetGraphFillImage(const std::string& GraphFillImage) {m_SpriteGraphFill.SetImage(GraphFillImage);};
	void				SetGraphFillColor(COLOR Color) {m_SpriteGraphFill.SetColor(Color);};
	void				SetGraphFillAdditive(bool Additive) {m_SpriteGraphFill.SetAdditive(Additive);};

	void				SetGraphPointImage(const std::string& GraphPointImage) {m_SpriteGraphPoint.SetImage(GraphPointImage);};
	void				SetGraphPointColor(COLOR Color) {m_SpriteGraphPoint.SetColor(Color);};
	void				SetGraphPointAdditive(bool Additive) {m_SpriteGraphPoint.SetAdditive(Additive);};
	void				SetGraphPointSize(const math::Vec2& GraphPointSize) {m_GraphPointSize = GraphPointSize;};

	void				SetGraphNodes(const std::vector<float>& NewNodes);

	void				SetTLOffset(const math::Vec2& HorOffset);
	void				SetBROffset(const math::Vec2& VerOffset);

	void				SetRangeAuto(bool IsAuto) {m_RangeAuto = IsAuto; RecalcNodes();};
	void				SetRange(const math::Vec2& Range) {m_Range = Range; RecalcNodes();};
	const math::Vec2&   GetRange() {return m_Range;};
	bool				GetRangeAuto() {return m_RangeAuto;};

	void				SetZeroHeight(float ZeroHeight);

	void				AddGraphLevel(float Value, math::Vec4 Color = math::Vec4(1.0f,1.0f,1.0f,1.0f), bool Additive = false) 
						{m_GraphLevels.push_back(GraphLevel(Value, Color, Additive));};
	void				RemoveGraphLevels() {m_GraphLevels.clear();};

	void				AddGraphMark(int Node, math::Vec4 Color = math::Vec4(1.0f,1.0f,1.0f,1.0f), bool Additive = false)
						{m_GraphMarks.push_back(GraphMark(Node,Color,Additive));};
	void				RemoveGraphMarks() {m_GraphMarks.clear();};

	void				RiseGraph() {m_CurGraphState = GS_RISING; m_CurHeightSpeed = m_HeightSpeed;};
	void				DropGraph() {m_CurGraphState = GS_DROPPING; m_CurHeightSpeed = m_HeightSpeed;};

	void				ForceDrop() {m_CurGraphState = GS_DROPPED; m_CurAnimFactor = 0.0f; RecalcNodes();};

	const math::Vec2&   GetGraphNodeCoords(int Node);

	//MEMBERS

protected:


	//METHODS
	
	void				RecalcGraphRect();
	void				RecalcNodes();

	//MEMBERS


	//widget params

	//height raising/dropping speed and axel
	float				m_HeightSpeed;
	float				m_HeightAxel;

	//values range
	bool				m_RangeAuto;
	math::Vec2			m_Range;

	//coords related
	math::Vec2			m_TLOffset;
	math::Vec2			m_BROffset;

	//graph nodes
	std::vector<float>  m_Nodes;

	//zero height
	float				m_ZeroHeight;

	//graph point size
	math::Vec2			m_GraphPointSize;

	//graph column width
	float				m_GraphColumnWidth;

	//column color
	math::Vec4			m_GraphColumnColor;

	//column every Nth node
	int					m_GraphColumnEvery;


	struct GraphLevel
	{
		float		    Value;
		float			CalculatedValue;
		math::Vec4      Color;
		bool			Additive;

		GraphLevel(float Val, math::Vec4 Col, bool Addit) 
		{Value = Val; Color = Col; Additive = Addit; CalculatedValue = 0.0f;};
		GraphLevel()
		{Value = 0.0f; Color = math::Vec4(1.0f,1.0f,1.0f,1.0f); CalculatedValue = 0.0f; Additive = false;}; 
	};

	//graph level params
	float				m_GraphLevelHeight;

	float				m_GraphLevelYShift;


	//graph mark params
	math::Vec2          m_GraphMarkSize;

	struct GraphMark
	{
		int				NodeIndex;
		math::Vec4		Color;
		bool			Additive;

		GraphMark()
		{NodeIndex = 0; Color = math::Vec4(1.0f,1.0f,1.0f,1.0f); Additive = false;};
		GraphMark(int NIndex, math::Vec4 Col, bool Addit)
		{NodeIndex = NIndex; Color = Col; Additive = Addit;};
	};







	//work members

	//graph node sprite
	TrSprite			m_SpriteGraphFill;

	//graph line point sprite
	TrSprite			m_SpriteGraphPoint;

	//graph column sprite
	TrSprite			m_SpriteGraphColumn;

	//graph level sprite
	TrSprite			m_SpriteGraphLevel;

	//graph mark sprite
	TrSprite			m_SpriteGraphMark;

	//graph rect
	math::Vec2			m_GraphTL;
	math::Vec2			m_GraphSize;
	bool				m_GraphRectValid;

	//calculated graph nodes data in screen coords system
	std::vector<float>  m_CalculatedNodes;

	//height factor (to be used later, for animations)
	float				m_CurAnimFactor;
	float				m_CurHeightSpeed;

	enum GRAPH_STATE
	{
		GS_RISING,
		GS_DROPPING,
		GS_RISEN,
		GS_DROPPED,
		GS_STATECOUNT
	};

	GRAPH_STATE			m_CurGraphState;



	//graph levels
	std::list<GraphLevel> m_GraphLevels;

	//graph marks
	std::list<GraphMark>  m_GraphMarks;
	

};//class UIGraph : public UIWidget


};//namespace ui





#endif